home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / web / spiderweb / fixes-to-be-applied / changes < prev    next >
Internet Message Format  |  1990-03-11  |  18KB

  1. From fubinf!thull Mon Mar 12 09:01:53 1990
  2. Received: by cs.Princeton.EDU (5.57/1.98)
  3.     id AA22774; Mon, 12 Mar 90 09:01:50 EST
  4. Received: from [129.217.64.60] by Princeton.EDU (5.58+++/2.32/mailrelay)
  5.     id AA20280; Mon, 12 Mar 90 08:59:12 EST
  6. Received: from fubinf.uucp 
  7.     by unido.informatik.uni-dortmund.de with uucp via EUnet (UNIDO-2.0.1.d)
  8.     for princeton.edu
  9.     id AO16211; Mon, 12 Mar 90 14:57:27 +0100
  10. Received: by fubinf.uucp (4.0/SMI-4.0)
  11.     id AA01394; Sat, 3 Nov 90 15:19:31 +0100
  12. Date: Sat, 3 Nov 90 15:19:31 +0100
  13. From: fubinf!thull (Klaus Thull)
  14. Message-Id: <9011031419.AA01394@fubinf.uucp>
  15. To: nr@Princeton.EDU
  16. Subject: spider.fixes
  17. Status: R
  18.  
  19. These changes made spider operational on several suns, one old
  20. 16bitter 68000 pcs cadmus, one 32bittter 68020 same,
  21. the sony news 68030, and the sony risc.
  22. please note that these changes refer to a version that came to me
  23. out of its own accord one day last summer and without bearing an exact date.
  24. please note that there is the issue of awk versions. I constantly
  25. have to take along one awk source to be sure to compile spider.
  26. please note that there is one extension as well: there is a symbolic
  27. printout in weave which has, in the case of knuths pascal-web,
  28. proven very handy.
  29. ::::::::::::::
  30. common.ch
  31. ::::::::::::::
  32. module 19
  33.  
  34. @d buf_size = 200 /* for \.{WEAVE} and \.{TANGLE} */
  35. @d long_buf_size = 500 /* for \.{WEAVE} */
  36.  
  37.  
  38. module 26
  39.  
  40. @d max_modules = 2000 /* number of identifiers, strings, module names;
  41.   must be less than 10240 */
  42.  
  43.  
  44. de-linting...
  45. @x module 29
  46. @ @<Add path name from {\tt -I} to search path@>=
  47.     pathaddname(*argv+2);
  48. @ @<Other...@>=
  49. @y
  50. @ @<Add path name from {\tt -I} to search path@>=
  51.     pathaddname(*argv+2);
  52. @ @<Other...@>=
  53. extern char* getenv();
  54. @z
  55.  
  56.  
  57. de-linting...
  58. @x module 33
  59. @ The included file name should only contain visible ASCII characters,
  60. @y
  61. @ The included file name should only contain visible ASCII characters,
  62. @z
  63.  
  64. @x
  65.       if ((cur_file=pathopen(cur_file_name,"r"))==NULL) {
  66. @y
  67.       if ((cur_file=pathopen(cur_file_name))==NULL) {
  68. @z
  69.  
  70.  
  71. @d max_bytes = 90000 /* the number of bytes in identifiers,
  72.   index entries, and module names */
  73. @d max_names = 4000 /* number of identifiers, strings, module names;
  74.   must be less than 10240 */
  75.  
  76. module 42
  77.  
  78. @d hash_size = 353 /* should be prime */
  79.  
  80.  
  81. @x module 62
  82. @ Some implementations may wish to pass the |history| value to the
  83. @y
  84. @ Some implementations may wish to pass the |history| value to the
  85. @z
  86.  
  87. activate stats
  88. @x
  89.   @<Print the job |history|@>;
  90. @y
  91. #ifdef STAT
  92.   print_stats();
  93. #endif
  94.   @<Print the job |history|@>;
  95. @z
  96.  
  97. de-linting...
  98. @x
  99. fatal("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n",0)@;
  100. else
  101. fatal("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n",
  102.     0);
  103. @y
  104. fatal("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n",
  105.     "")@;
  106. else
  107. fatal("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n",
  108.     "");
  109. @z
  110. ::::::::::::::
  111. spider.ch
  112. ::::::::::::::
  113.  
  114. escape backslash...
  115. (and put titles right)
  116. #x module 11
  117. #  We write tokens out to two files: |scrapfile| for \.{WEAVE}, and
  118. #y
  119. #  We write tokens out to two files: |scrapfile| for \.{WEAVE}, and
  120. #z
  121.  
  122. |ttokfile| for \.{TANGLE}.
  123. #<Set init...#>=
  124.     scrapfile = "scraps.web"
  125. #x
  126.     print "@*Scrap code generated by {\tt SPIDER}." > scrapfile
  127.     ttokfile = "outtoks.web"
  128.     print "@*Token code generated by {\tt SPIDER}." > scrapfile
  129. #y
  130.     print "@*Scrap code generated by {\\tt SPIDER}." > scrapfile
  131.     ttokfile = "outtoks.web"
  132.     print "@*Token code generated by {\\tt SPIDER}." > ttokfile
  133. #z
  134.  
  135. escape backslash...
  136. #x module 16
  137. # We use a special file to write grammar information:
  138. #<Set init...#>=
  139.     grammarfile = "grammar.web"
  140.     print "@*Grammar code generated by {\tt SPIDER}." > grammarfile
  141. #y
  142. # We use a special file to write grammar information:
  143. #<Set init...#>=
  144.     grammarfile = "grammar.web"
  145.     print "@*Grammar code generated by {\\tt SPIDER}." > grammarfile
  146. #z
  147.  
  148. escape backslash...
  149. #x module 62
  150. # This is how we write out the string or constant scrap, at the end.
  151. #y
  152. # This is how we write out the string or constant scrap, at the end.
  153. #z
  154.  
  155. #x
  156.     " and \TeX\ strings are identified." > scrapfile
  157. #y
  158.     " and \\TeX\\ strings are identified." > scrapfile
  159. #z
  160.  
  161. #x module 72
  162. # We use an ugly trick to get the token numbers different for
  163. #y
  164. # We use an ugly trick to get the token numbers different for
  165. #z
  166.  
  167. #x
  168.             temp = temp + #'37 - highesttoken ## hackety hack!
  169. #y
  170.             temp = temp + #'37  + 3 - highesttoken ## hackety hack!
  171.                 ## +3 because three highest are already defined!
  172. #z
  173.  
  174.  
  175. #x module 126
  176. # It's desirable to put the production in a comment, but we have to
  177. get rid of the confusing \vert, or \.{WEAVE} will think it introduces
  178. code.
  179. #<Remove \vert\ from |inputline[n]| and put results in |this_string|#>=
  180.         this_string = inputline[n]
  181.         tempi = index(this_string,"|")
  182.         while (tempi != 0) {
  183.             tempa = substr(this_string,1,tempi-1)
  184.             tempb = substr(this_string,tempi+1)
  185.             this_string = tempa "\\vert " tempb
  186.             tempi = index(this_string,"|")
  187.             }
  188. #y
  189. # It's desirable to put the production in a comment, but we have to
  190. get rid of the confusing \vert, or \.{WEAVE} will think it introduces
  191. code. And of other things as well\dots
  192. #<Remove \vert\ from |inputline[n]| and put results in |this_string|#>=
  193.         tempb = inputline[n]
  194.         tempa = ""
  195.         tempi = index(tempb,"\\")
  196.         while (tempi != 0) {
  197.             tempa = tempa substr(tempb,1,tempi-1) "\\BS "
  198.             tempb = substr(tempb,tempi+1)
  199.             tempi = index(tempb,"\\")
  200.             }
  201.         this_string = tempa tempb
  202.         tempb = this_string
  203.         tempa = ""
  204.         tempi = index(tempb,"##")
  205.         while (tempi != 0) {
  206.             tempa = tempa substr(tempb,1,tempi-1) "\\##"
  207.             tempb = substr(tempb,tempi+1)
  208.             tempi = index(tempb,"##")
  209.             }
  210.         this_string = tempa tempb
  211.         tempb = this_string
  212.         tempa = ""
  213.         tempi = index(tempb,"$")
  214.         while (tempi != 0) {
  215.             tempa = tempa substr(tempb,1,tempi-1) "\\$"
  216.             tempb = substr(tempb,tempi+1)
  217.             tempi = index(tempb,"$")
  218.             }
  219.         this_string = tempa tempb
  220.         tempb = this_string
  221.         tempa = ""
  222.         tempi = index(tempb,"%")
  223.         while (tempi != 0) {
  224.             tempa = tempa substr(tempb,1,tempi-1) "\\%"
  225.             tempb = substr(tempb,tempi+1)
  226.             tempi = index(tempb,"%")
  227.             }
  228.         this_string = tempa tempb
  229.         tempb = this_string
  230.         tempa = ""
  231.         tempi = index(tempb,"^")
  232.         while (tempi != 0) {
  233.             tempa = tempa substr(tempb,1,tempi-1) "\\^"
  234.             tempb = substr(tempb,tempi+1)
  235.             tempi = index(tempb,"^")
  236.             }
  237.         this_string = tempa tempb
  238.         tempb = this_string
  239.         tempa = ""
  240.         tempi = index(tempb,"@")
  241.         while (tempi != 0) {
  242.             tempa = tempa substr(tempb,1,tempi-1) "\\@@"
  243.             tempb = substr(tempb,tempi+1)
  244.             tempi = index(tempb,"@")
  245.             }
  246.         this_string = tempa tempb
  247.         tempi = index(this_string,"|")
  248.         while (tempi != 0) {
  249.             tempa = substr(this_string,1,tempi-1)
  250.             tempb = substr(this_string,tempi+1)
  251.             this_string = tempa "\\vert " tempb
  252.             tempi = index(this_string,"|")
  253.             }
  254.         tempi = index(this_string,"'")
  255.         while (tempi != 0) {
  256.             tempa = substr(this_string,1,tempi-1)
  257.             tempb = substr(this_string,tempi+1)
  258.             this_string = tempa "\\RQ " tempb
  259.             tempi = index(this_string,"'")
  260.             }
  261.         tempi = index(this_string,"`")
  262.         while (tempi != 0) {
  263.             tempa = substr(this_string,1,tempi-1)
  264.             tempb = substr(this_string,tempi+1)
  265.             this_string = tempa "\\LQ " tempb
  266.             tempi = index(this_string,"`")
  267.             }
  268.         tempi = index(this_string,"{")
  269.         while (tempi != 0) {
  270.             tempa = substr(this_string,1,tempi-1)
  271.             tempb = substr(this_string,tempi+1)
  272.             this_string = tempa "\\LB " tempb
  273.             tempi = index(this_string,"{")
  274.             }
  275.         tempi = index(this_string,"}")
  276.         while (tempi != 0) {
  277.             tempa = substr(this_string,1,tempi-1)
  278.             tempb = substr(this_string,tempi+1)
  279.             this_string = tempa "\\RB " tempb
  280.             tempi = index(this_string,"}")
  281.             }
  282.         tempi = index(this_string,"~")
  283.         while (tempi != 0) {
  284.             tempa = substr(this_string,1,tempi-1)
  285.             tempb = substr(this_string,tempi+1)
  286.             this_string = tempa "\\TL " tempb
  287.             tempi = index(this_string,"~")
  288.             }
  289.         tempi = index(this_string,"_")
  290.         while (tempi != 0) {
  291.             tempa = substr(this_string,1,tempi-1)
  292.             tempb = substr(this_string,tempi+1)
  293.             this_string = tempa "\\UL " tempb
  294.             tempi = index(this_string,"_")
  295.             }
  296.         tempi = index(this_string,"&")
  297.         while (tempi != 0) {
  298.             tempa = substr(this_string,1,tempi-1)
  299.             tempb = substr(this_string,tempi+1)
  300.             this_string = tempa "\\AM " tempb
  301.             tempi = index(this_string,"&")
  302.             }
  303. #z
  304.  
  305.  
  306. activate this if year is field no 8
  307.  
  308.  x module 151
  309. #*1Tracking the generation date.
  310.  y
  311. #*1Tracking the generation date.
  312.  z
  313.  
  314.  x
  315.     year = $7
  316.  y
  317.     year = $8
  318.  z
  319.  
  320. ::::::::::::::
  321. tangle.ch
  322. ::::::::::::::
  323.  
  324. @ The following parameters were sufficient in the original \.{TANGLE} to
  325. handle \TeX, so they should be sufficient for most applications of \.{TANGLE}.
  326.  
  327. If you change |max_bytes|, |max_names| or |hash_size| you should also
  328. change them in the file |"common.web"|.
  329.  
  330. @d max_bytes = 90000 /* the number of bytes in identifiers,
  331.   index entries, and module names; used in |"common.web"| */
  332. @d max_toks = 150000 /* number of bytes in compressed \cee\ code */
  333. @d max_names = 4000 /* number of identifiers, strings, module names;
  334.   must be less than 10240; used in |"common.web"| */
  335. @d max_texts = 2000 /* number of replacement texts, must be less than 10240 */
  336. @d hash_size = 353 /* should be prime; used in |"common.web"| */
  337. @d longest_name = 400 /* module names shouldn't be longer than this */
  338. @d stack_size = 50 /* number of simultaneous levels of macro expansion */
  339. @d buf_size = 100 /* for \.{WEAVE} and \.{TANGLE} */
  340.  
  341. de-linting...
  342. @x
  343. @ Here's the procedure that decides whether a name of length |l|
  344. starting at position |first| equals the identifier pointed to by |p|:
  345.  
  346. @u
  347. names_match(p,first,l)
  348. name_pointer p; /* points to the proposed match */
  349. ASCII *first; /* position of first character of string */
  350. int l; /* length of identifier */
  351. @y
  352. @ Here's the procedure that decides whether a name of length |l|
  353. starting at position |first| equals the identifier pointed to by |p|:
  354.  
  355. @u
  356. names_match(p,first,l,t)
  357. name_pointer p; /* points to the proposed match */
  358. ASCII *first; /* position of first character of string */
  359. int l; /* length of identifier */
  360. eight_bits t; /* which is a dummy but lint complains */
  361.   /* it will still complain \dots */
  362. @z
  363.  
  364.  
  365.  
  366. 12-char significance
  367. @x module 110
  368. @ We use macros with zero or more parameters, and we give the parameters names.
  369. @y
  370. @ We use macros with zero or more parameters, and we give the parameters names.
  371. @z
  372.  
  373. @x
  374. @d max_param_name_texts = 256
  375. @y
  376.  
  377. Identifier conflict with PCS C\dots
  378.  
  379. @d param_name_texts_end = p_nm_txts_end
  380. @d next_param_name_text = next_p_nm_txt
  381. @#
  382. @d max_param_name_texts = 256
  383. @z
  384.  
  385. de-linting
  386. @x
  387. @ This function prints out a decimal constant using |app_repl|.
  388. @u
  389. app_decimal(c)
  390.     int c; /* on entry require |c>=0| */
  391. {int power;
  392. @y
  393. @ This function prints out a decimal constant using |app_repl|.
  394. This casting trick is due to Tim Morgan's WEB-C.
  395.  
  396. @d app_decimal(x) = zapp_decimal((long)(x))
  397.  
  398. @u
  399. zapp_decimal(c)
  400.     long c; /* on entry require |c>=0| */
  401. {long power;
  402. @z
  403. ::::::::::::::
  404. weave.ch
  405. ::::::::::::::
  406.  
  407. @x module 1
  408. #ifdef STAT
  409.   @<Print statistics about memory usage@>;
  410. #endif STAT
  411. @y
  412. @z
  413.  
  414. module 2
  415. @ The following parameters were sufficient in the original \.{WEAVE} to
  416. handle \TeX, so they should be sufficient for most applications of \.{CWEAVE}.
  417.  
  418. @d max_bytes = 90000 /* the number of bytes in identifiers,
  419.   index entries, and module names */
  420. @d max_names = 4000 /* number of identifiers, strings, module names;
  421.   must be less than 10240 */
  422. @d max_modules = 2000 /* greater than the total number of modules */
  423. @d hash_size = 353 /* should be prime */
  424. @d buf_size = 100 /* maximum length of input line, plus one */
  425. @d longest_name = 400 /* module names and strings shouldn't be longer than this */
  426. @d long_buf_size = 500 /* |buf_size+longest_name| */
  427. @d line_length = 80 /* lines of \TeX\ output have at most this many characters;
  428.   should be less than 256 */
  429. @d max_refs = 20000 /* number of cross-references; must be less than 65536 */
  430. @d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
  431.   must be less than 65536 */
  432. @x
  433. @d max_texts = 2000 /* number of phrases in \cee\ texts being parsed;
  434.   must be less than 10240 */
  435. @d max_scraps = 1000 /* number of tokens in \cee\ texts being parsed */
  436. @y
  437. @d max_texts = 4000 /* number of phrases in \cee\ texts being parsed;
  438.   must be less than 10240 */
  439. @d max_scraps = 4000 /* number of tokens in \cee\ texts being parsed */
  440. @z
  441. @d stack_size = 400 /* number of simultaneous output levels */
  442.  
  443. @x
  444. /* identifier =200 or octal @'310 */
  445. @y
  446. /* identifier =200 or octal |@'310| */
  447. @z
  448.  
  449. @x module 57
  450. @ In the \TeX\ part of a module, cross-reference entries are made only for
  451. @y
  452. @ In the \TeX\ part of a module, cross-reference entries are made only for
  453. @z
  454.  
  455. @x doesn't belong here
  456. #ifdef DEBUG
  457.     case trace: tracing=next_control-'0'; continue;
  458. #endif DEBUG
  459. @y
  460. @z
  461.  
  462.  
  463. Print symbolically the entire tree
  464.  
  465. @x module 87
  466. @ Token lists in |@!tok_mem| are composed of the following kinds of
  467. @y
  468. @ Token lists in |@!tok_mem| are composed of the following kinds of
  469. @z
  470.  
  471.  
  472. @u
  473. #ifdef DEBUG
  474. @x
  475. print_text(p) /* prints a token list */
  476. text_pointer p;
  477. @y
  478. print_text(p,ind) /* prints a token list */
  479. text_pointer p;
  480. int ind;
  481. @z
  482. {
  483.   token_pointer j; /* index into |tok_mem| */
  484.   sixteen_bits r; /* remainder of token after the flag has been stripped off */
  485.   if (p>=text_ptr) printf("BAD");
  486.   if (p>=text_ptr) printf("BAD");
  487.   else for (j=*p; j<*(p+1); j++) {
  488.     r=*j%id_flag;
  489.     r=*j%id_flag;
  490.     switch (*j/id_flag) {
  491.       case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
  492.  /* |id_flag| */
  493.       case 2: printf("\&{"); print_id((name_dir+r)); printf("}"); break;
  494.  /* |res_flag| */
  495.       case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
  496.         /* |mod_flag| */
  497. @x
  498.       case 4: printf("[[%d]]",r); break; /* |tok_flag| */
  499.       case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
  500. @y
  501.       case 4:  /* we make this a recursive prettyprinting here */
  502.         printf("@@/\n");
  503.         { int i; for (i=0; i<ind; i++) printf(" "); }
  504.         printf("[[%d:",r);
  505.         print_text(r+tok_start,ind+1);
  506.         printf("]]");
  507.         break; /* |tok_flag| */
  508.       case 5:
  509.         printf("@@/\n");
  510.         { int i; for (i=0; i<ind; i++) printf(" "); }
  511.         printf("|[[%d:",r);
  512.         print_text(r+tok_start,ind+1);
  513.         printf("]]|");
  514.         break; /* |inner_tok_flag| */
  515. @z
  516.       default: @<Print token |r| in symbolic form@>;
  517.     }
  518.   }
  519. }
  520. #endif DEBUG
  521.  
  522. @x module 106
  523. @ @<If semi-tracing, show the irreducible scraps@>=
  524. #ifdef DEBUG
  525. @y
  526. @ @<If semi-tracing, show the irreducible scraps@>=
  527. #ifdef DEBUG
  528.   if (tracing==2)
  529.   {
  530.     scrap_pointer k;
  531.     printf("\nafter...\n");
  532.     for (k=scrap_base; k<=lo_ptr; k++)
  533.     { print_cat(k->cat); printf(", %ld:<",(long)(k->trans-tok_start)); 
  534.       print_text(k->trans,0); printf(">");
  535.     }
  536.     new_line;
  537.   }
  538. @z
  539. if (lo_ptr>scrap_base && tracing==1) {
  540.   printf("\nIrreducible scrap sequence in section %d:",module_count);
  541.   mark_harmless;
  542.   for (j=scrap_base; j<=lo_ptr; j++) {
  543.     printf(" "); print_cat(j->cat);
  544.   }
  545. }
  546. #endif DEBUG
  547.  
  548. @x module 107
  549. @ @<If tracing,...@>=
  550. #ifdef DEBUG
  551. if (tracing==2) {
  552.   printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
  553.   if (loc>buffer+50) {
  554.     printf("...");
  555.     ASCII_write(loc-51,51);
  556.   }
  557.   else ASCII_write(buffer+1,loc-buffer);
  558. }
  559. #endif DEBUG
  560. @y
  561. @ @<If tracing,...@>=
  562. #ifdef DEBUG
  563. if (tracing==2) {
  564.   scrap_pointer k;
  565.   printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
  566.   if (loc>buffer+50) {
  567.     printf("...");
  568.     ASCII_write(loc-51,51);
  569.   }
  570.   else ASCII_write(buffer,loc-buffer);
  571.   printf("\nbefore...\n");
  572.   for (k=scrap_base; k<scrap_ptr; k++)
  573.   { print_cat(k->cat); printf(", %ld:<",(long)(k->trans-tok_start)); 
  574.     print_text(k->trans,0); printf(">\n");
  575.   }
  576.   new_line;
  577. }
  578. #endif DEBUG
  579. @z
  580.  
  581. @x module 144
  582. @ In the \TeX\ part of a module, we simply copy the source text, except that
  583. @y
  584. @ In the \TeX\ part of a module, we simply copy the source text, except that
  585. @z
  586.  
  587. @x
  588.     case vertical_bar: /* surround vertical bar with \.{\\CD...\\DC} */
  589. @y
  590. #ifdef DEBUG
  591.     case trace: tracing=*(loc-1)-'0'; continue;
  592. #endif DEBUG
  593.     case vertical_bar: /* surround vertical bar with \.{\\CD...\\DC} */
  594. @z
  595.  
  596.  
  597.  
  598. @x module 262
  599. @ @<Print statistics about memory usage@>=
  600. printf(
  601. "\nMemory usage statistics: %d of %d names, %d of %d cross-references,\n",
  602.   name_ptr-name_dir, name_dir_end-name_dir,
  603.   xref_ptr-xmem, xmem_end-xmem);
  604. printf("\t %d of %d bytes;",byte_ptr-byte_mem,byte_mem_end-byte_mem);
  605. printf("\nParsing required %d of %d(%d) scraps, %d of %d(%d) texts,\n",
  606.   max_scr_ptr-scrap_info, max_scraps, max_scraps-SCRAP_SLACK,
  607.   max_text_ptr-tok_start, max_texts, max_texts-TEXT_SLACK
  608.   );
  609. printf("\t %d of %d(%d) tokens, %d of %d levels;\n",
  610.   max_tok_ptr-tok_mem, max_toks, max_toks-TOK_SLACK,
  611.   max_stack_ptr-stack, stack_end-stack
  612.   );
  613. printf("\nSorting required %d levels\n", max_sort_ptr-scrap_info);
  614. @y
  615. @ @u print_stats() {
  616. #ifdef STAT
  617. printf(
  618. "\nMemory usage statistics: %d of %d names, %d of %d cross-references,\n",
  619.   name_ptr-name_dir, name_dir_end-name_dir,
  620.   xref_ptr-xmem, xmem_end-xmem);
  621. printf("\t %d of %d bytes;",byte_ptr-byte_mem,byte_mem_end-byte_mem);
  622. printf("\nParsing required %d of %d(%d) scraps, %d of %d(%d) texts,\n",
  623.   max_scr_ptr-scrap_info, max_scraps, max_scraps-SCRAP_SLACK,
  624.   max_text_ptr-tok_start, max_texts, max_texts-TEXT_SLACK
  625.   );
  626. printf("\t %d of %d(%d) tokens, %d of %d levels;\n",
  627.   max_tok_ptr-tok_mem, max_toks, max_toks-TOK_SLACK,
  628.   max_stack_ptr-stack, stack_end-stack
  629.   );
  630. printf("\nSorting required %d levels\n", max_sort_ptr-scrap_info);
  631. #endif
  632. }
  633. @z
  634.  
  635. @x
  636. #ifdef STAT
  637.   @<Print statistics about memory usage@>;
  638. #endif STAT
  639. @y
  640. @z
  641.  
  642.